package cn.minimelon.api.service.data.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.minimelon.api.domain.data.ModelQueryVO;
import cn.minimelon.api.domain.module.vo.DataModelVO;
import cn.minimelon.api.domain.module.vo.DataPropVO;
import cn.minimelon.api.domain.module.vo.ModelFullVO;
import cn.minimelon.api.service.data.ModelDeployService;
import cn.minimelon.api.service.data.constants.DataConstants;
import cn.minimelon.api.service.data.utils.SQLRunnerUtils;
import cn.minimelon.api.service.module.IDtbModelService;
import lombok.extern.slf4j.Slf4j;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.util.ResourceUtil;
import org.noear.solon.data.cache.CacheService;

import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class ModelDeployServiceImpl implements ModelDeployService {
    @Inject
    private GroupTemplate groupTemplate;

    @Inject
    private CacheService cacheService;

    @Inject
    private IDtbModelService dtbModelService;

    @Override
    public void createDynamicsTable(DataModelVO model) throws IOException, SQLException {
        String dynamicsTpl = ResourceUtil.getResourceAsString("init/data_dynamics_tables.tpl");
        Template template = groupTemplate.getTemplate(dynamicsTpl);
        template.binding(buildVariable(model));
        String renderSql = template.render();
        log.info("renderSql:{}", renderSql);
        SQLRunnerUtils.execScript(renderSql);
    }

    @Override
    public void removeModelCache(DataModelVO model) {
        String cacheKey = StrUtil.format(DataConstants.MODEL_CACHE_TEMPLATE, model.getAreaCode(), model.getCode());
        cacheService.remove(cacheKey);
    }

    @Override
    public ModelFullVO selectFullInfo(ModelQueryVO query) {
        String cacheKey = StrUtil.format(DataConstants.MODEL_CACHE_TEMPLATE, query.getAreaCode(), query.getModelCode());
        ModelFullVO fullInfo = cacheService.get(cacheKey, ModelFullVO.class);
        if (fullInfo == null) {
            fullInfo = selectDataModel(query);
            fullInfo.setPropList(selectPropList(query));
        }
        return fullInfo;
    }

    @Override
    public List<DataPropVO> selectPropList(ModelQueryVO query) {
        List<DataPropVO> list = dtbModelService.selectPropList(query);
        if (CollUtil.isNotEmpty(list)) {
            for (DataPropVO pp : list) {
                pp.setColCode(StrUtil.toCamelCase(pp.getColCode()));
                pp.setCode(StrUtil.toCamelCase(pp.getCode()));
            }
        }
        return list;
    }

    @Override
    public ModelFullVO selectDataModel(ModelQueryVO query) {
        return dtbModelService.selectDataModel(query);
    }

    private Map<String, Object> buildVariable(DataModelVO model) {
        Map<String, Object> vals = new HashMap<>();
        vals.put("code", model.getCode().toLowerCase());
        vals.put("areaCode", model.getAreaCode().toLowerCase());
        int strCol = Solon.cfg().getInt("melon.module.strCol", 10);
        int numCol = Solon.cfg().getInt("melon.module.numCol", 5);
        int dateCol = Solon.cfg().getInt("melon.module.dateCol", 5);
        vals.put("strCol", strCol);
        vals.put("numCol", numCol);
        vals.put("dateCol", dateCol);
        return vals;
    }
}
